import React, { Fragment } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import BaseComponent from '../../components/common/baseComponent.js';
import FilterModal from '../../components/oilStation/stationFilterModal';
import List from '../../components/oilStation/stationList';
import Map from '../../components/oilStation/map';
import AreaModal from '../../components/oilStation/areaListModal';
import { debounced } from '../../utils/func';
import locationIcon from '../../../assets/images/station/location.png';
import toast from '../../utils/toast';
import { inWechat } from '../../utils/wechat';
import StationCell from '../../components/oilStation/stationCell';
import ActionSheet from '../../components/common/actionSheet';
import StaionNoMatchModal from '../../components/oilStation/stationNoMatch';
import { openNav } from '../../utils/map';

import icSearch from '../../../assets/images/station/ic_search@2x.png';
import icMap from '../../../assets/images/station/ic_map@2x.png';
import icMapHover from '../../../assets/images/station/ic_map_hover@2x.png';

let oldCoord = {};

@connect(({ oilStation, global }) => {
  return {
    dataList: oilStation.get('dataList'),
    searchList: oilStation.get('searchList'),
    provinceList: oilStation.get('provinceList'),
    geoData: global.get('geoData'),
    brandList: oilStation.get('brandList'),
    distanceList: oilStation.get('distanceList'),
    currentCity: oilStation.get('currentCity'),
    mapList: oilStation.get('mapList'),
    geoStatus: oilStation.get('geoStatus'),
    currentStation: oilStation.get('currentStation'),
  };
})
class StationList extends BaseComponent {
  static propTypes = {
    canRefuel: PropTypes.bool,
    typeChanged: PropTypes.func,
    cls: PropTypes.shape({
      filterCls: PropTypes.string,
    }),
  }

  static defaultProps = {
    canRefuel: false,
    cls: {
      filterCls: '',
    },
  }
  state = {
    type: 'list',
    showMap: false,
    keyword: '',
    selectedIndex: 0,
    coord: {
      x: 0,
      y: 0,
    },
  }

  componentDidMount() {
    this.props.dispatch({
      type: 'oilStation/initData',
    });
  }

  refreshGeo = () => {
    this.props.dispatch({
      type: 'oilStation/doGeo',
    });
  }

  requestData = debounced((page) => {
    const { dataList, geoData, brandList, distanceList } = this.props;
    const selectedBrand = brandList.find(item => item.get('selected'));
    const selectedDistance = distanceList.find(item => item.get('selected'));

    this.props.dispatch({
      type: 'oilStation/fetchStationList',
      payload: {
        lat: geoData.get('latitude'),
        lon: geoData.get('longitude'),
        targetPage: page || (dataList.get('page') + 1),
        pageSize: 10,
        source: window.source,
        distance: selectedDistance ? selectedDistance.get('distance') : null,
        brand: selectedBrand && selectedBrand.get('code') !== '0' ? selectedBrand.get('code') : null,
      },
    });
  }, 300);

  requestMapData = debounced(() => {
    const { geoData, distanceList, brandList } = this.props;
    const selectedBrand = brandList.find(item => item.get('selected'));
    const selectedDistance = distanceList.find(item => item.get('selected'));

    this.props.dispatch({
      type: 'oilStation/fetchMapList',
      payload: {
        lat: geoData.get('latitude'),
        lon: geoData.get('longitude'),
        targetPage: 1,
        pageSize: 100000,
        source: window.source,
        distance: selectedDistance ? selectedDistance.get('distance') : null,
        brand: selectedBrand && selectedBrand.get('code') !== '0' ? selectedBrand.get('code') : null,
      },
    });
  }, 300);

  searchData = debounced((page) => {
    const { searchList, geoData, provinceList } = this.props;
    const { keyword } = this.state;
    // if (!keyword) {
    //   return;
    // }
    const params = {
      lat: geoData.get('latitude'),
      lon: geoData.get('longitude'),
      targetPage: page || (searchList.get('page') + 1),
      pageSize: 10,
      source: window.source,
      gasStationName: keyword,
    };
    const province = provinceList.find(p => p.get('selected'));
    if (province && province.get('id') !== -1) {
      params.province = province.get('name');
      const city = province.get('children').find(c => c.get('selected'));
      if (city && city.get('id') !== -1) {
        params.city = city.get('name');
        const area = city.get('children').find(a => a.get('selected'));
        if (area && area.get('id') !== -1) {
          params.distict = area.get('name');
        }
      }
    }
    this.props.dispatch({
      type: 'oilStation/searchStation',
      payload: params,
    });
  }, 500);

  changeMap = () => {
    this.changeType('list');
    const { typeChanged } = this.props;
    if (typeChanged) {
      typeChanged(!this.state.showMap);
    }
    if (!this.state.showMap) {
      this.requestMapData();
    }
    this.setState({
      showMap: !this.state.showMap,
    });
  }

  changeType = (type) => {
    const { typeChanged } = this.props;
    if (typeChanged) {
      typeChanged(type !== 'list');
    }
    this.setState({ type });
    if (type === 'search') {
      this.searchData(1);
      setTimeout(() => {
        this.input.focus();
      }, 500);
    }
  }

  cickFilter = (type) => {
    this.filter.show(type);
  }

  selectFilter = (type, value) => {
    if (type === 'brand') {
      this.setState({ selectedBrand: value });
    } else {
      this.setState({ selectedDistance: value });
    }
    this.props.dispatch({
      type: 'oilStation/selectFilter',
      payload: {
        type,
        value,
      },
    });
    const { showMap } = this.state;
    if (showMap) {
      this.requestMapData();
    } else {
      this.requestData(1);
    }
    this.filter.close();
  }

  clickNav = (station) => {
    if (inWechat() && window.wx && station.get('lat')) {
      window.wx.ready(() => {
        window.wx.openLocation({
          latitude: Number(station.get('lat')), // 纬度，浮点数，范围为90 ~ -90
          longitude: Number(station.get('lng')), // 经度，浮点数，范围为180 ~ -180。
          name: station.get('name'), // 位置名
          address: station.get('address'), // 地址详情说明
          scale: 28, // 地图缩放级别,整形值,范围从1~28。默认为最大
          // infoUrl: '' // 在查看位置界面底部显示的超链接,可点击跳转
        });
      });
    } else if (!station.get('lat')) {
      console.error('该油站没有坐标');
    } else {
      toast('请在微信中使用');
    }
  }

  clickRefuel = (station) => {
    this.props.dispatch({
      type: 'oilStation/doGeo',
    });
    const { currentStation } = this.props;
    console.log('click --- refule', station, currentStation);
    if (currentStation && station.get('id') === currentStation.get('id')) {
      this.goRefuel(station);
    } else {
      this.nomatch.show(station);
    }
  }

  goRefuel = (station) => {
    this.props.history.push({
      pathname: 'refuel',
      state: { station },
    });
  }

  rechoose = () => {
    this.nomatch.close();
  }

  clickTel = (station) => {
    if (station.get('phone')) {
      window.location.href = `tel:${station.get('phone')}`;
    }
  }

  clickArea = (e) => {
    e.stopPropagation();
    this.area.show();
  }

  selectStation = (selectedIndex) => {
    this.setState({ selectedIndex });
  }

  selectArea = (province, city, area) => {
    this.props.dispatch({
      type: 'oilStation/selectArea',
      payload: {
        province,
        city,
        area,
      },
    });
    if (
      area ||
      (city && city.get('id') === -1) ||
      (province && province.get('id') === -1)
    ) {
      this.area.close();
      this.searchData(1);
    }
  }

  keywordChanged = (e) => {
    if (e.target.value !== this.state.keyword) {
      this.setState({ keyword: e.target.value });
      this.searchData(1);
    }
  }

  selectNav = (station) => {
    this.actionSheet.show({
      title: '请选择地图',
      options: [
        {
          title: '百度地图',
          action: () => {
            this.actionSheet.close();
            openNav({
              map: 'BAIDU',
              to: {
                lat: station.get('lat'),
                lng: station.get('lng'),
                address: station.get('address'),
              },
            });
          },
        },
        {
          title: '高德地图',
          action: () => {
            this.actionSheet.close();
            openNav({
              map: 'GAODE',
              to: {
                lat: station.get('lat'),
                lng: station.get('lng'),
                address: station.get('address'),
              },
            });
          },
        },
      ],
    });
  }

  computeCoord = (gx, gy) => {
    const scope = 30;

    let touchX = gx;
    let touchY = gy;
    if (touchX >= window.innerWidth - scope) {
      touchX = window.innerWidth - scope;
    } else if (touchX <= scope) {
      touchX = scope;
    }
    if (touchY >= window.innerHeight - scope) {
      touchY = window.innerHeight - scope;
    } else if (touchY <= scope) {
      touchY = scope;
    }

    return { touchX, touchY };
  }

  // 快捷图标拖拽
  shortcutTouchStart = (e) => {
    const list = window.document.querySelectorAll('.list')[0];
    if (list) {
      list.style.cssText = 'overflow-y: hidden;';
      window.document.querySelectorAll('body')[0].style.cssText = 'position:fixed;left:0;top:0;';
    }
    const touch = e.targetTouches[0];
    const { touchX, touchY } = this.computeCoord(touch.pageX, touch.pageY);

    oldCoord = {
      ...e.targetTouches[0],
      pageX: touchX,
      pageY: touchY,
    };
  }

  shortcutTouchMove = (e) => {
    const touch = e.targetTouches[0];
    const {
      coord: {
        x,
        y,
      },
    } = this.state;
    const { touchX, touchY } = this.computeCoord(touch.pageX, touch.pageY);
    this.setState({
      coord: {
        x: x + (touchX - oldCoord.pageX),
        y: y + (touchY - oldCoord.pageY),
      },
    });
    oldCoord = {
      ...touch,
      pageX: touchX,
      pageY: touchY,
    };
  }

  shortcutTouchEnd = () => {
    const list = window.document.querySelectorAll('.list')[0];
    if (list) {
      list.style.cssText = 'overflow-y: scroll;';
      setTimeout(() => {
        window.document.querySelectorAll('body')[0].style.cssText = 'position:initial;';
      }, 600);
    }
  }

  renderLoading = () => {
    const { geoStatus } = this.props;
    let view;
    if (geoStatus === 'loading') {
      view = (
        <div className="no-location">
          <img src={locationIcon} alt="" className="icon" />
          <p className="text">正在定位中....</p>
        </div>
      );
    } else if (geoStatus === 'fail') {
      view = (
        <div className="no-location">
          <img src={locationIcon} alt="" className="icon" />
          <p className="text">无法定位，请检查定位服务是否开启<br />可点击“搜索框“搜索油站</p>
        </div>
      );
    }
    return view;
  }

  renderSearch = () => {
    const {
      provinceList, searchList, currentStation, canRefuel,
    } = this.props;
    const { keyword } = this.state;
    let title = '全国';
    const province = provinceList.find(p => p.get('selected'));
    if (province && province.get('id') !== -1) {
      title = province.get('name');
      const city = province.get('children').find(c => c.get('selected'));
      if (city && city.get('id') !== -1) {
        title = city.get('name');
        const area = city.get('children').find(a => a.get('selected'));
        if (area && area.get('id') !== -1) {
          title = area.get('name');
        }
      }
    }
    return (
      <div className="station-list">
        <div className="search-header">
          <div className="input-view" onClick={() => this.input.focus()}>
            <div className="header-title" onClick={this.clickArea}>{title}</div>
            <i className="iconfont icon-trangle" />
            <div className="line" />
            <i className="iconfont icon-search" />
            <input
              className="input"
              type="search"
              placeholder="油站搜索"
              value={keyword}
              onChange={this.keywordChanged}
              ref={input => this.input = input}
            />
          </div>
          <div className="cancel" onClick={() => this.changeType('list')}>取消</div>
        </div>
        { this.renderShortcut() }
        <List hasMore={searchList.get('hasMore')} list={searchList.get('list')} loadMore={this.searchData} openNav={this.selectNav} canRefuel={canRefuel} refuelFunc={this.clickRefuel} currentStation={currentStation} />
      </div>
    );
  }

  renderList = () => {
    const {
      showMap, selectedIndex,
    } = this.state;
    const {
      dataList, mapList, geoData, geoStatus, currentStation, canRefuel,
      distanceList, brandList,
    } = this.props;

    const selectedDistance = distanceList.find(item => item.get('selected'));
    const selectedBrand = brandList.find(item => item.get('selected'));
    let contentView;
    if (showMap) {
      let selectedView;
      const station = mapList.get(selectedIndex);
      // console.log('======', station, selectedIndex, dataList);
      if (station) {
        selectedView = <StationCell station={station} type="map" actionSheet={this.actionSheet} openNav={this.selectNav} canRefuel={canRefuel} refuelFunc={this.clickRefuel} currentStation={currentStation} single />;
      }
      contentView = (
        <Fragment>
          { this.renderShortcut() }
          <Map
            stationList={mapList}
            center={[geoData.get('lng'), geoData.get('lat')]}
            selectFunc={this.selectStation}
            geoData={geoData}
            distance={selectedDistance ? selectedDistance.get('distance') : null}
          />
          {selectedView}
        </Fragment>
      );
    } else if (geoStatus === 'success') {
      contentView = (
        <Fragment>
          { this.renderShortcut() }
          <List draging={this.state.draging} hasMore={dataList.get('hasMore')} list={dataList.get('list')} loadMore={this.requestData} openNav={this.selectNav} canRefuel={canRefuel} refuelFunc={this.clickRefuel} currentStation={currentStation} />
        </Fragment>
      );
    } else {
      contentView = this.renderLoading();
    }
    return (
      <div className="station-list">
        <div className="filter-view">
          <div className="filter-cell" onClick={() => this.cickFilter('distance')}>
            <div>{selectedDistance ? selectedDistance.get('name') : '油站距离'}</div>
            <i className="iconfont icon-trangle" />
          </div>
          <div className="filter-cell" onClick={() => this.cickFilter('brand')}>
            <div>{selectedBrand ? selectedBrand.get('name') : '全部品牌'}</div>
            <i className="iconfont icon-trangle" />
          </div>
          <div className="ic-search-box" onClick={() => this.changeType('search')}>
            <img src={icSearch} alt="加载失败" className="ic-search" />
          </div>
        </div>
        {contentView}
      </div>
    );
  }

  renderShortcut = () => {
    const {
      coord: {
        x,
        y,
      },
      showMap,
    } = this.state;
    return (
      <img alt="" draggable="true" style={{ transform: `translate(${x}px,${y}px)` }} className="station-shortcut" src={showMap ? icMapHover : icMap} onClick={this.changeMap} onTouchStart={this.shortcutTouchStart} onTouchMove={this.shortcutTouchMove} onTouchEnd={this.shortcutTouchEnd} />
    );
  }

  render() {
    const { type, showMap } = this.state;
    const {
      brandList, distanceList, provinceList, cls,
    } = this.props;
    console.log('cls-----', cls);
    const contentView = type === 'list' ? this.renderList() : this.renderSearch();

    return (
      <Fragment>
        {contentView}
        <ActionSheet ref={actionSheet => this.actionSheet = actionSheet} />
        <StaionNoMatchModal
          ref={nomatch => this.nomatch = nomatch}
          goOnFunc={this.goRefuel}
          reChooseFunc={this.rechoose}
        />
        <FilterModal
          ref={filter => this.filter = filter}
          selectFunc={this.selectFilter}
          brandList={brandList}
          distanceList={distanceList}
          showMap={showMap}
          className={cls.filterCls}
        />
        <AreaModal
          ref={area => this.area = area}
          provinceList={provinceList}
          selectFunc={this.selectArea}
        />
      </Fragment>
    );
  }
}

export default StationList;
